<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <video autoplay="autoplay" muted controls src="http://1256414354.vod2.myqcloud.com/5a9b9a4dvodtranscq1256414354/affbc6755285890795852028706/v.f30.mp4"></video>
</body>
<script src="./src/ts/Stack.js"></script>
<script>  
    //  执行上下文  包括
    // context = {
    //     "'VO'/'AO'": {'variable Object':'...',},  变量对象
    //     "[[scoped]]": [],                     作用域链
    //     this:  ()=> { return context }        this
    // }
    console.log("初始化执行上下文栈")
    const contextStack = new Stack(); // 执行上下文栈

    const globalContext = {
        'VO': {
            value: undefined,
            person: 'reference to function person(){}',
            run: 'reference to function run(){}',
        },

        // this: () => { globalContext }
    }
    globalContext.Scope = [
        globalContext['VO']
    ],


        console.log("创建全局执行上下文")
    console.log("初始化全局执行上下文变量对象")
    console.log("初始化全局执行上下文作用域链")
    contextStack.push(globalContext)
    console.log("将全局执行上下文压入执行上下文栈")
    contextStack.printTable()

    // 将作用域链保存至 [[scoped]] 属性中

    person['[[scoped]]'] = run['[[scoped]]'] = globalContext['Scope']
    console.log('函数创建，保存作用域链到[[scoped]]属性！')

    //  词法作用域（静态）
    var value = 1
    globalContext['VO'] = {
        ...globalContext['VO'],
        value: 1
    }
    console.log("赋值操作，修改变量对象")
    contextStack.printTable()
    function person(params) {
        console.log('person函数被激活')
        const personContext = {
            'AO': {
                arguments: {
                    length: 0
                },
            },
            // this: () => { runContext }
        }
        personContext.Scope = Array.prototype.concat.call([], [personContext['AO']], person['[[scoped]]'])
        console.log("创建person执行上下文")
        console.log("初始化person执行上下文变量对象")
        console.log("初始化person执行上下文作用域链，将[[scoped]]属性赋值给执行上下文，将激活的对象绑定在作用域链前端")

        contextStack.push(personContext)
        console.log("将person执行上下文压入执行上下文栈，开始执行person函数")
        contextStack.printTable()
        console.log(value)  //1
        console.log("person执行完毕，准备出栈")
        contextStack.pop()
        console.log("person执行上下文出栈")
        contextStack.printTable()
    }
    function run(params) {

        console.log('run函数被激活')
        const runContext = {
            'AO': {
                arguments: {
                    length: 0
                },
                value: undefined,
                name: 'reference to function name(){}',
            },

            // this: () => { runContext }
        }
        runContext.Scope = Array.prototype.concat.call([], [runContext['AO']], run['[[scoped]]'])
        console.log("创建run执行上下文")
        console.log("初始化run执行上下文变量对象")
        console.log("创建name函数")
        name['[[scoped]]'] = runContext['Scope']
        console.log('name函数创建，保存作用域链到[[scoped]]属性！')

        console.log("初始化run执行上下文作用域链，将[[scoped]]属性赋值给执行上下文，将激活的对象绑定在作用域链前端")
        contextStack.push(runContext)
        console.log("将run执行上下文压入执行上下文栈，开始执行run函数")
        contextStack.printTable()
        var value = 2;
        runContext['AO'] = {
            ...runContext['AO'],
            value: 2
        }
        person()
        function name(params) {
            console.log('name函数被激活')
            const nameContext = {
                'AO': {
                    arguments: {
                        length: 0
                    },
                },

                // this: () => { runContext }
            }
            nameContext.Scope = Array.prototype.concat.call([], [nameContext['AO']], name['[[scoped]]'])
            console.log("创建name执行上下文")
            console.log("初始化name执行上下文变量对象")
            console.log("初始化name执行上下文作用域链，将[[scoped]]属性赋值给执行上下文，将激活的对象绑定在作用域链前端")

            contextStack.push(nameContext)
            console.log("将name执行上下文压入执行上下文栈，开始执行name函数")
            contextStack.printTable()
            console.log(111)
            console.log("name执行完毕，准备出栈")
            contextStack.pop()
            console.log("name执行上下文出栈")
            contextStack.printTable()
        }
        console.log("run执行完毕，准备出栈")
        contextStack.pop()
        console.log("run执行上下文出栈")
        contextStack.printTable()
        return name
    }
    run()()
    console.log("所有操作执行完毕！准备出栈")
    contextStack.printTable()
    contextStack.pop()
    console.log("全局上下文出栈！")
    contextStack.printTable()


</script>

</html>